package com.study_platform.consumer.util;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.study_platform.consumer.WebSocketServer;
import com.study_platform.entity.Pk;
import com.study_platform.entity.ProblemSolvingRecord;
import com.study_platform.entity.Question;
import com.study_platform.entity.User;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

public class Game extends Thread{
    private Player A, B;
    private List<Question> questions;
    private Integer result = 2; //1a赢，0b赢，2平局
    private String status = "playing";//  playing or finished
    private ReentrantLock lock = new ReentrantLock();
    private String nextAnswerA;
    private String nextAnswerB;
    private Integer grade;
    private String point;
    public Game(Integer aId, Integer bId, Integer grade, String point){
        questions = new ArrayList<>();
        A = new Player(aId, new ArrayList<>());
        B = new Player(bId, new ArrayList<>());
        this.grade = grade;
        this.point = point;
    }
    public Player getPlayerA() {//返回玩家A
        return A;
    }

    public Player getPlayerB() {//返回玩家B
        return B;
    }
    private void sendAllMessage(String message) {//发送所有消息
        System.out.println("发送message = " + message);
        if (WebSocketServer.users.get(A.getUserId()) != null)
            WebSocketServer.users.get(A.getUserId()).sendMessage(message);
        if (WebSocketServer.users.get(B.getUserId()) != null)
            WebSocketServer.users.get(B.getUserId()).sendMessage(message);
    }

    public void createQuestions(){//创建试卷
        questions = WebSocketServer.testPaperService.createPaper(grade.toString(), point, WebSocketServer.testPaperService.getTestId(), "5");
    }

    private boolean nextChoice() throws InterruptedException {//判断是否获取了下一步操作
        Thread.sleep(1 * 1000);
        for (int i = 0; i < 200; i ++ ) {
            try {
                Thread.sleep(200);
                lock.lock();
                try {
                    if (nextAnswerA != null && nextAnswerB != null) {
                        A.getAnswer().add(nextAnswerA);
                        B.getAnswer().add(nextAnswerB);
                        return true;
                    }
                    if(A.getAnswer().size() == questions.size() && B.getAnswer().size() == questions.size()){
                        status = "finished";
                        return true;
                    }

                } finally {
                    lock.unlock();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return false;
    }

    private void judge(){//判断比赛结果
        List<String> ansA = A.getAnswer();
        List<String> ansB = B.getAnswer();
        int numa = 0, numb = 0;
        for(int i = 0; i < Math.min(ansB.size() ,ansA.size()) && i < questions.size(); i++){
            if (ansA.get(i).equalsIgnoreCase(questions.get(i).getAnswer())){
                numa++;
                ProblemSolvingRecord one = new ProblemSolvingRecord(null, questions.get(i).getQuestionId(),WebSocketServer.testPaperService.getTestId(), A.getUserId(), null, ansA.get(i));
                WebSocketServer.problemSolvingRecordService.saveOrUpdate(one);
            }

            if (ansB.get(i).equalsIgnoreCase(questions.get(i).getAnswer())){
                numb++;
                ProblemSolvingRecord one = new ProblemSolvingRecord(null, questions.get(i).getQuestionId(),WebSocketServer.testPaperService.getTestId(), B.getUserId(), null, ansB.get(i));
                WebSocketServer.problemSolvingRecordService.saveOrUpdate(one);
            }
        }

        if (numa > numb){
            result = 1;
        } else if (numa == numb) {
            result = 2;
        } else {
            result = 0;
        }
        System.out.println("第" + Math.min(ansB.size() ,ansA.size()) + "次结果: " + result);
    }

    public List<Question> getQuestions() {
        return questions;
    }

    public void setNextAnswerStepA(String answer) {//将A下一步答案存下
        lock.lock();
        try {
            this.nextAnswerA = answer;
        } finally {
            lock.unlock();
        }
    }
    public void setNextAnswerStepB(String answer) {//将B下一步答案存下
        lock.lock();
        try {
            this.nextAnswerB = answer;
        } finally {
            lock.unlock();
        }
    }
    private void sendNext() {  // 向两个Client传递下一题信息
        lock.lock();
        try {
            JSONObject resp = new JSONObject();
            resp.put("event", "next");
            resp.put("a_answer", nextAnswerA);
            resp.put("b_answer", nextAnswerB);
            sendAllMessage(resp.toJSONString());
            nextAnswerA = nextAnswerB = null;
        } finally {
            lock.unlock();
        }
    }

    @Override
    public void run(){
        System.out.println("开始对战");
        for (int i = 0; i < 10; i++) {
            System.out.println("Questions" + questions);
            try {
                if (nextChoice()) {  // 是否获取了两个玩家的下一步操作
                    judge();
                    if (status.equals("playing")) {//正在游戏则进行下一步
                        sendNext();
                    } else {//否则结束游戏，发送结果
                        break;
                    }
                } else {
                    lock.lock();
                    try {
                        if (nextAnswerA == null && nextAnswerB == null) {//如果两个都没有进行操作，则结束对战
                            status = "finished";
                            break;
                        } else if (nextAnswerA == null) {//如果只有一位玩家没有回答则判断该玩家该题不会，将其答案置空
                            nextAnswerA = "";
                        } else {
                            nextAnswerB = "";
                        }
                        nextChoice();
                        judge();
                    } finally {
                        lock.unlock();
                    }
                }
                if (Math.max(A.getAnswer().size(), B.getAnswer().size()) >= questions.size()){
                    break;
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        sendResult();
        System.out.println("对战结束");
    }

    private void sendResult() {  // 向两个Client公布结果
        JSONObject resp = new JSONObject();
        resp.put("event", "result");
        if (result == 1){
            resp.put("result", A.getUserId());
        }else if (result == 0){
            resp.put("result", B.getUserId());
        }else{
            resp.put("result", 0);
        }
        saveToDatabase();
        sendAllMessage(resp.toJSONString());
    }

    private void saveToDatabase() {
        User userA = WebSocketServer.userMapper.selectById(A.getUserId());
        User userB = WebSocketServer.userMapper.selectById(B.getUserId());
        if (result.equals(0)){
            userA.setRating(userA.getRating() - 50);
            userB.setRating(userB.getRating() + 50);
        } else if (result.equals(1)) {
            userA.setRating(userA.getRating() + 50);
            userB.setRating(userB.getRating() - 50);
        }
        WebSocketServer.userMapper.updateById(userA);
        WebSocketServer.userMapper.updateById(userB);
        WebSocketServer.pkMapper.insert(new Pk(null, getPlayerA().getUserId(), getPlayerB().getUserId(), WebSocketServer.testPaperService.getTestId() - 1, new Timestamp(System.currentTimeMillis()), result));
    }


}
